use axum::extract::{Path, Query};
use axum::{Router, Json};
use axum::routing::{get, post};
use serde::{Serialize,Deserialize};
use tower_cookies::Cookies;

use crate::models::{User, Comment, CreateComment, Guide, CreateGuide, UpdateComment, UpdateGuide, ImageShare, CreateImageShare, UpdateImageShare};
use crate::utils::cookie;

type RouterResult<T> = Result<T,String>;


// struct RouterResponse {

// }

#[derive(Deserialize,Serialize)]
struct ImageShareResponse{
    pub discription:String,
    pub status:String,
    pub image_share_id:String,
    pub comment_id:String,
}

impl ImageShareResponse{
    pub fn ok(discription:String,image_share_id:String,comment_id:String) -> ImageShareResponse {
        ImageShareResponse { discription, status: "ok".to_string(), image_share_id, comment_id}
    }

    pub fn err(discription:String,image_share_id:String,comment_id:String) -> ImageShareResponse {
        ImageShareResponse { discription, status: "err".to_string(), image_share_id, comment_id}
    }

}


pub fn router() -> Router {
    Router::new()
        .route("/", get(index))
        .route("/make_comment", post(make_comment))
        .route("/update_comment", post(update_comment))
        .route("/delete_comment", get(delete_comment))
        .route("/make_image_share", post(make_image_share))
        .route("/update_image_share", post(update_image_share))
        .route("/delete_image_share", get(delete_image_share))
        .route("/get_all",get(get_all))
}

async fn index(cookies:Cookies) -> RouterResult<String> {
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap();

    let user_id: i32 = user_id.parse().unwrap();

    let user = User::fetch_one_by_id(user_id).await.map_err(|err| err.to_string())?;

    Ok(format!("欢迎来到ImageShare 特权首页，{}！",user.nickname))

}


async fn get_all(cookies:Cookies) -> Json<Vec<ImageShare>> {
    // let guides = Guide::fetch_all().await.unwrap();
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap();
    let user_id:i32 = user_id.parse().unwrap();
    let image_shares = ImageShare::fetch_all_by_author_id(user_id).await.unwrap();


    Json(image_shares)

}


/// 发表图片评论
async fn make_comment(Json(comment):Json<CreateComment>,cookies:Cookies) -> Json<ImageShareResponse> {
    let user_id:i32 = cookie::get_user_id_from_cookie(cookies).unwrap().parse().unwrap();
    // let user = get_user_from_cookies(cookies).await;
    // if user_id.is_none() {
    //     return Json(ImageShareResponse::err("未登录".to_string(), "".to_string(), "".to_string()));
    // }

    // 建立一个comment
    let comment_id = Comment::insert(user_id, comment.content, comment.rate, "status".to_string()).await.map_err(|err| err.to_string());

    if let Err(err) = comment_id {
        return Json(ImageShareResponse::err(err, "".to_string(), "".to_string()));
    }
    let comment_id = comment_id.unwrap();

    let mut image_share = ImageShare::fetch_one_by_id(comment.of_id).await.unwrap();
    let res = image_share.push_comment(comment_id).await;

    // let res =  push_comment_by_id(guide_id, comment_id).await.map_err(|err| err.to_string());
    if let Err(err) = res {
        return Json(ImageShareResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    // Json(serde_json::json!({
    //     "comment_id":comment_id
    // }))
    Json(ImageShareResponse::ok("成功发表评论".to_string(), image_share.id.to_string(), comment_id.to_string()))
}


#[derive(Serialize,Deserialize)]
struct DeleteComment {
    pub image_share_id: i32,
    pub comment_id: i32
}

/// 删除 comment
async fn delete_comment(Query(query):Query<DeleteComment>,cookies:Cookies) -> Json<ImageShareResponse> {
    // let user_id = get_user_id_from_cookies(cookies).unwrap();
    let user_id:i32 = cookie::get_user_id_from_cookie(cookies).unwrap().parse().unwrap();

    let mut image_share = ImageShare::fetch_one_by_id(query.image_share_id).await.unwrap();


    //1. 验证 comment是否是当前用户发送的


    //2. 从comments表中删除该comment
    if let Err(res) = Comment::delete_by_id(query.comment_id).await.map_err(|err| err.to_string()){
        return Json(ImageShareResponse::err(res, "".to_string(), "".to_string()));
    }
    
    //3. 将ImageShare对象中包含的该评论的评论号码删除

    if let Err(err) = image_share.pop_comment(query.comment_id).await {
        return Json(ImageShareResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    // Json(serde_json::json!({
    //     "discription":"删除评论成功！",
    //     "status":"ok"
    // }))
    Json(ImageShareResponse::ok("删除评论成功！".to_string(), "".to_string(), "".to_string()))

}

/// 更新攻略评论
async fn update_comment(Json(comment):Json<UpdateComment>,cookies:Cookies) -> Json<ImageShareResponse> {

    // 更新comment
    if let Err(err) = Comment::update_part_by_id(comment.id, comment.content, comment.rate).await.map_err(|err| err.to_string()){
        return Json(ImageShareResponse::err(err, "".to_string(), "".to_string()));
    }

    Json(ImageShareResponse::ok("更新评论成功".to_string(), "".to_string(), "".to_string()))
}

/// 发表美图
async fn make_image_share(Json(ci): Json<CreateImageShare>,cookies:Cookies) -> Json<ImageShareResponse>{
    // let user = get_user_from_cookies(cookies).await;
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap().parse().unwrap();

    // if let Err(err) = user {
    //     return Json(GuideResponse::err(err, "".to_string(), "".to_string()));
    // }
    // let user = user.unwrap();

    let image_share =  ImageShare::insert(user_id, ci.image, ci.content, ci.image_type, vec![], "status".to_string()).await;
    if let Err(err) = image_share {
        return Json(ImageShareResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    let image_share_id = image_share.unwrap();



    Json(ImageShareResponse::ok("发表美图推荐成功！".to_string(), image_share_id.to_string(), "".to_string()))

}

/// 更新美图
async fn update_image_share(Json(ui):Json<UpdateImageShare>,cookies:Cookies) -> Json<ImageShareResponse> {
    // let res = Guide::update_all_by_id(guide.id, guide.guide_type, guide.content, guide.image, comments, status)
    // let res = Guide::update_part_by_id(guide.id, guide.guide_type, guide.content, guide.image).await.map_err(|err| err.to_string());


    let res = ImageShare::update_part_by_id(ui.id, ui.image, ui.content, ui.image_type).await;

    if let Err(err) = res {
        return Json(ImageShareResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    Json(ImageShareResponse::ok("更新美图成功！".to_string(), ui.id.to_string(), "".to_string()))
}


#[derive(Serialize,Deserialize)]
struct DeleteImageShare {
    pub image_share_id: i32
}

/// 删除 美图
async fn delete_image_share(Query(query):Query<DeleteImageShare>,cookies:Cookies) -> Json<ImageShareResponse> {
    let res = ImageShare::delete_by_id(query.image_share_id).await;

    if let Err(err) = res{
        return Json(ImageShareResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    Json(ImageShareResponse::ok("删除美图成功！".to_string(), query.image_share_id.to_string(), "".to_string()))

}

// async fn recommendation() -> Json<ImageShareResponse>

